package com.cskaoyan.wordmemorize.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.common.MyHeaderReadListener;
import com.cskaoyan.wordmemorize.common.MyReadListener;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.VocConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.*;
import com.cskaoyan.wordmemorize.dto.app.DisplayBookVocDTO;
import com.cskaoyan.wordmemorize.dto.app.DisplayChapterDTO;
import com.cskaoyan.wordmemorize.dto.app.DisplayVocInterpretationDTO;
import com.cskaoyan.wordmemorize.dto.app.UserBookStatisticsDTO;
import com.cskaoyan.wordmemorize.request.*;
import com.cskaoyan.wordmemorize.service.FileUploadService;
import com.cskaoyan.wordmemorize.service.VocService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class VocServiceImpl implements VocService {

    @Autowired
    VocMapper vocMapper;

    @Autowired
    VocConverter vocConverter;

    @Autowired
    VocMeaningMapper vocMeaningMapper;

    @Autowired
    ExampleSentenceMapper exampleSentenceMapper;

    @Autowired
    VocChapBookMapper vocChapBookMapper;

    @Autowired
    VocChapterMapper vocChapterMapper;

    @Autowired
    VocBookMapper vocBookMapper;

    @Autowired
    FileUploadService fileUploadService;

    @Autowired
    VocService vocService;


    @Override
    public PageDTO<VocDTO> getVocabularies(VocPageRequest pageQuery) {
        if (pageQuery.getPageNum() == null || pageQuery.getBookId() == null || pageQuery.getChapterId() == null) {
            int pageNum = pageQuery.getPageNum() != null ? pageQuery.getPageNum() : 1;
            Page<VocDO> pageParam1 = new Page<>(pageNum, 10);
            Page<VocDO> vocabularyInfo = vocMapper.getVocabularyInfo(null,
                    null,
                    null, pageParam1);


            return vocConverter.vocList2Page(vocabularyInfo.getRecords(), (long) vocabularyInfo.getTotal());
        }
        Page<VocDO> pageParam = new Page<>(pageQuery.getPageNum(), pageQuery.getCount());

        Page<VocDO> vocabularyInfo = vocMapper.getVocabularyInfo(Long.parseLong(pageQuery.getBookId()),
                Long.parseLong(pageQuery.getChapterId()),
                pageQuery.getKeyword(), pageParam);


        // 8. 转换并返回分页结果
        return vocConverter.vocList2Page(vocabularyInfo.getRecords(), vocabularyInfo.getTotal());

    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_ADD)
    public void addVoc(VocCommand command) {
        LambdaQueryWrapper<VocDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VocDO::getContent, command.getContent());

        VocDO vocDO = vocMapper.selectOne(queryWrapper);
        if (vocDO != null) {
            throw new BusinessException(ResultCodeEnum.VOC_EXISTED);
        }
        VocDO voc = vocConverter.command2VocDO(command);
        vocMapper.insert(voc);

        List<VocMeaningCommand> interpretations = command.getInterpretations();
        List<VocMeaningDO> vocMeaningDOS = vocConverter.commands2VocMeaningDOs(interpretations);
        if (!CollectionUtils.isEmpty(vocMeaningDOS)) {
            vocMeaningDOS.forEach(vocMeaningDO -> {
                vocMeaningDO.setVocId(voc.getId());
                vocMeaningMapper.insert(vocMeaningDO);
            });
        }

        List<ExampleSentenceCommand> examples = command.getExamples();
        List<ExampleSentenceDO> exampleSentenceDOS = vocConverter.commands2ExampleSentenceDOs(examples);
        if (!CollectionUtils.isEmpty(exampleSentenceDOS)) {
            exampleSentenceDOS.forEach(exampleSentenceDO -> {
                exampleSentenceDO.setVocId((voc.getId()));
                exampleSentenceMapper.insert(exampleSentenceDO);
            });
        }

        List<VocChapBookCommand> relations = command.getRelations();
        List<VocChapBookDO> vocChapBookDOS = vocConverter.commands2VocChapBookDOs(relations);
        if (!CollectionUtils.isEmpty(vocChapBookDOS)) {
            vocChapBookDOS.forEach(vocChapBookDO -> {
                vocChapBookDO.setVocId(voc.getId());
                vocChapBookMapper.insert(vocChapBookDO);

                // 修改章节书籍中的单词数量
                LambdaUpdateWrapper<VocChapterDO> chapterWrapper = new LambdaUpdateWrapper<>();
                chapterWrapper.eq(vocChapBookDO.getChapterId() != null, VocChapterDO::getId, vocChapBookDO.getChapterId())
                        .eq(vocChapBookDO.getChapterName() != null, VocChapterDO::getChapterName, vocChapBookDO.getChapterName())
                        .setSql("voc_count = voc_count + 1");

                vocChapterMapper.update(chapterWrapper);


                LambdaUpdateWrapper<VocBookDO> BookWrapper = new LambdaUpdateWrapper<>();
                BookWrapper.eq(vocChapBookDO.getBookId() != null, VocBookDO::getId, vocChapBookDO.getBookId())
                        .eq(vocChapBookDO.getBookName() != null, VocBookDO::getName, vocChapBookDO.getBookName())
                        .setSql("voc_count = voc_count + 1");

                vocBookMapper.update(BookWrapper);
            });
        }

    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateVoc(VocCommand command) {

        // 更新voc表
        VocDO voc = vocConverter.command2VocDO(command);
        vocMapper.updateById(voc);

        // 更新vocMeaning表
        List<VocMeaningCommand> interpretations = command.getInterpretations();
        List<VocMeaningDO> vocMeaningDOS = vocConverter.commands2VocMeaningDOs(interpretations);
        if (!CollectionUtils.isEmpty(vocMeaningDOS)) {
            vocMeaningDOS.forEach(vocMeaningDO -> {
                vocMeaningMapper.updateById(vocMeaningDO);
            });
        }

        // 更新vocExample表
        List<ExampleSentenceCommand> examples = command.getExamples();
        List<ExampleSentenceDO> exampleSentenceDOS = vocConverter.commands2ExampleSentenceDOs(examples);
        if (!CollectionUtils.isEmpty(exampleSentenceDOS)) {
            exampleSentenceDOS.forEach(exampleSentenceDO -> {
                exampleSentenceMapper.updateById(exampleSentenceDO);
            });
        }

        // 更新vocChapterBook表
        List<VocChapBookCommand> relations = command.getRelations();
        List<VocChapBookDO> newRelations = vocConverter.commands2VocChapBookDOs(relations);
        if (!CollectionUtils.isEmpty(newRelations)) {
            // 1. 先处理旧关联（减少计数）

            List<VocChapBookDO> oldRelations = vocChapBookMapper.selectList(
                    new LambdaQueryWrapper<VocChapBookDO>()
                            .eq(VocChapBookDO::getVocId, command.getId())
            );

            decrementCount(oldRelations); // 旧关系计数-1

            // 2. 处理新关联（增加计数）
            incrementCount(newRelations); // 新关系计数+1
        }

    }

    private void decrementCount(List<VocChapBookDO> relations) {
        if (CollectionUtils.isEmpty(relations)) return;

        relations.forEach(rel -> {
            // 章节计数-1
            if (rel.getChapterId() != null) {
                vocChapterMapper.update(null,
                        new LambdaUpdateWrapper<VocChapterDO>()
                                .eq(VocChapterDO::getId, rel.getChapterId())
                                .setSql("voc_count = voc_count - 1")
                );
            }

            // 书籍计数-1
            vocBookMapper.update(null,
                    new LambdaUpdateWrapper<VocBookDO>()
                            .eq(VocBookDO::getId, rel.getBookId())
                            .setSql("voc_count = voc_count - 1")
            );
        });
    }

    private void incrementCount(List<VocChapBookDO> relations) {
        if (CollectionUtils.isEmpty(relations)) return;

        relations.forEach(rel -> {
            // 章节计数+1
            if (rel.getChapterId() != null) {
                vocChapterMapper.update(null,
                        new LambdaUpdateWrapper<VocChapterDO>()
                                .eq(VocChapterDO::getId, rel.getChapterId())
                                .setSql("voc_count = voc_count + 1")
                );
            }

            // 书籍计数+1
            vocBookMapper.update(null,
                    new LambdaUpdateWrapper<VocBookDO>()
                            .eq(VocBookDO::getId, rel.getBookId())
                            .setSql("voc_count = voc_count + 1")
            );

            vocChapBookMapper.insertOrUpdate(rel);
        });
    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteVocOperateDTO deleteVocabulary(Long vocId) {
        VocDO vocDO = vocMapper.selectById(vocId);


        List<VocMeaningDO> vocMeaningDOS = vocMeaningMapper.selectList(
                new LambdaQueryWrapper<VocMeaningDO>()
                        .eq(VocMeaningDO::getVocId, vocId)
        );

        List<ExampleSentenceDO> exampleSentenceDOS = exampleSentenceMapper.selectList(
                new LambdaQueryWrapper<ExampleSentenceDO>()
                        .eq(ExampleSentenceDO::getVocId, vocId)
        );

        // 3. 处理关联的章节和书籍计数（先于删除操作）
        List<VocChapBookDO> relations = vocChapBookMapper.selectList(
                new LambdaQueryWrapper<VocChapBookDO>()
                        .eq(VocChapBookDO::getVocId, vocId)
        );
        vocDO.setInterpretations(vocMeaningDOS);
        vocDO.setExamples(exampleSentenceDOS);
        DeleteVocOperateDTO deleteVocOperateDTO = vocConverter.toDeleteVocOperateDTO(vocDO);

        if (!CollectionUtils.isEmpty(relations)) {
            // 减少关联的章节和书籍计数
            relations.forEach(relation -> {
                // 章节计数-1
                if (relation.getChapterId() != null) {
                    vocChapterMapper.update(null,
                            new LambdaUpdateWrapper<VocChapterDO>()
                                    .eq(VocChapterDO::getId, relation.getChapterId())
                                    .setSql("voc_count = voc_count - 1")
                    );
                }

                // 书籍计数-1
                vocBookMapper.update(null,
                        new LambdaUpdateWrapper<VocBookDO>()
                                .eq(VocBookDO::getId, relation.getBookId())
                                .setSql("voc_count = voc_count - 1")
                );

            });

        }

        // 4. 删除所有关联数据（按从属关系顺序）
        vocMeaningMapper.delete(
                new LambdaQueryWrapper<VocMeaningDO>()
                        .eq(VocMeaningDO::getVocId, vocId)
        );

        exampleSentenceMapper.delete(
                new LambdaQueryWrapper<ExampleSentenceDO>()
                        .eq(ExampleSentenceDO::getVocId, vocId)
        );

        vocChapBookMapper.delete(
                new LambdaQueryWrapper<VocChapBookDO>()
                        .eq(VocChapBookDO::getVocId, vocId)
        );

        // 5. 最后删除单词主体
        vocMapper.deleteById(vocId);

        return deleteVocOperateDTO;
    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_BATCH_DELETE)
    public List<DeleteVocOperateDTO> deleteVocabularies(BatchDeleteCommand command) {
        List<Long> ids = command.getIds().stream()
                .map(Long::parseLong)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }

        // 1. 查询所有要删除的单词
        List<VocDO> vocList = vocMapper.selectBatchIds(ids);

        // 2. 准备返回结果
        List<DeleteVocOperateDTO> results = new ArrayList<>();

        // 3. 批量处理每个单词的删除逻辑
        ids.forEach(vocId -> {
            DeleteVocOperateDTO result = this.deleteVocabulary(vocId);
            results.add(result);
        });

        return results;
    }

    @Override
    public List<VocChapBookDTO> getVocRelations(Long vocId) {

        // 2. 查询基础关系数据
        List<VocChapBookDO> relations = vocChapBookMapper.selectList(
                new LambdaQueryWrapper<VocChapBookDO>()
                        .eq(VocChapBookDO::getVocId, vocId)
        );
        for (VocChapBookDO relation : relations) {
            VocBookDO vocBookDO = vocBookMapper.selectOne(new LambdaQueryWrapper<VocBookDO>()
                    .eq(VocBookDO::getId, relation.getBookId()));
            relation.setCategoryId(vocBookDO.getBcId());
            relation.setCategoryName(vocBookDO.getBcName());
        }
        return CollectionUtils.isEmpty(relations) ?
                Collections.emptyList() :
                vocConverter.vocChapBookDOs2DTOs(relations);
    }

    @Autowired
    UserNotRememberMapper userNotRememberMapper;
    @Autowired
    UserVocRevMapper userVocRevMapper;
// wrapper和mapper每查一次会建立一次多表连接(在别的表中查找也要遍历)，效率太慢，改为sql语句，sql语句是一条语句直接将多表连接
// 并遍历查找 而且还有索引
//    @Override
//    public PageDTO<DisplayBookVocDTO> getDisplayBookVocsInfo(AppVocPageRequest pageRequest) {
//        //在voc_chap_book表中查询获取所有该书籍的单词id列表
//        LambdaQueryWrapper<VocChapBookDO> vocIdQueryWrapper = new LambdaQueryWrapper<>();
//        vocIdQueryWrapper.eq(VocChapBookDO::getBookId, pageRequest.getBookId());
//        List<VocChapBookDO> vocChapBookDOS = vocChapBookMapper.selectList(vocIdQueryWrapper);
//        List<Long> vocIds = vocChapBookDOS.stream().map(VocChapBookDO::getVocId).collect(Collectors.toList());
//        //根据vocIds从voc表中选出vocDO
//        LambdaQueryWrapper<VocDO> vocQueryWrapper = new LambdaQueryWrapper<>();
//        vocQueryWrapper.in(VocDO::getId, vocIds);
//        //实现分页查询并先将当前页转化为list方便下面的步骤进行
//        List<VocDO> vocDOS = new ArrayList<>();
//        if(pageRequest.getPageNum()!=0){
//            Page<VocDO> pageParam = new Page<>(pageRequest.getPageNum(), pageRequest.getCount());
//            Page<VocDO> vocDOPage = vocMapper.selectPage(pageParam, vocQueryWrapper);
//            vocDOS = vocDOPage.getRecords();
//        }else {
//            vocDOS = vocMapper.selectList(vocQueryWrapper);
//        }
//
//        //vocDOS关联user_not_remember表
//        vocDOS.forEach(vocDO -> {
//            LambdaQueryWrapper<UserNotRememberDO> userNotRememberQueryWrapper = new LambdaQueryWrapper<>();
//            userNotRememberQueryWrapper.eq(UserNotRememberDO::getVocId, vocDO.getId())
//                    //注意绑定用户
//                    .eq(UserNotRememberDO::getUserId, pageRequest.getUserId());
//            UserNotRememberDO isNotRemember = userNotRememberMapper.selectOne(userNotRememberQueryWrapper);
//            if (isNotRemember != null) {
//                vocDO.setNotRemember(0);
//            } else {
//                vocDO.setNotRemember(1);
//            }
//        });
//        //vocDOS关联user_reviewed表
//        vocDOS.forEach(vocDO -> {
//            LambdaQueryWrapper<UserVocRevDO> userReviewedQueryWrapper = new LambdaQueryWrapper<UserVocRevDO>();
//            userReviewedQueryWrapper.eq(UserVocRevDO::getVocId, vocDO.getId())
//                    .eq(UserVocRevDO::getUserId, pageRequest.getUserId());
//            UserVocRevDO isReviewed = userVocRevMapper.selectOne(userReviewedQueryWrapper);
//            if (isReviewed != null) {
//                vocDO.setReviewed(1);
//            } else {
//                vocDO.setReviewed(0);
//            }
//        });
//        //vocDOS关联voc_meaning表
//        vocDOS.forEach(vocDO -> {
//            LambdaQueryWrapper<VocMeaningDO> vocMeaningQueryWrapper = new LambdaQueryWrapper<>();
//            vocMeaningQueryWrapper.eq(VocMeaningDO::getVocId, vocDO.getId());
//            List<VocMeaningDO> vocMeaningDOS = vocMeaningMapper.selectList(vocMeaningQueryWrapper);
//            vocDO.setInterpretations(vocMeaningDOS);
//        });
//
//        //converter转化为DisplayBookVocDTO
//        PageDTO<DisplayBookVocDTO> displayBookVocDTOPageDTO = vocConverter.displayBookVocList2Page(vocDOS, (long) vocDOS.size());
//        return displayBookVocDTOPageDTO;
//    }

    @Override
    public PageDTO<DisplayBookVocDTO> getDisplayBookVocsInfo(AppVocPageRequest pageRequest){
        List<VocDO> list;
        pageRequest.setUserId(pageRequest.getUserId()==null?"0":pageRequest.getUserId());
        pageRequest.setBookId(pageRequest.getBookId()==null?"0":pageRequest.getBookId());
        list = vocMapper.getVocsOfUserBook(
                Long.valueOf(pageRequest.getUserId()), Long.valueOf(pageRequest.getBookId()),pageRequest.getPageNum(),pageRequest.getCount());
        int total = vocMapper.countChaptersInBook(pageRequest.getBookId());
        PageDTO<DisplayBookVocDTO> displayBookVocDTOPageDTO = vocConverter.displayBookVocList2Page(list, (long) total);
        return displayBookVocDTOPageDTO;
    }

    @Override
    public PageDTO<DisplayChapterDTO> getDisplayBookChapterVocsInfo(AppVocPageRequest pageRequest) {
        List<VocChapterDO> list = new ArrayList<>();
        String userIdStr = pageRequest.getUserId();
        long userId = Long.parseLong(userIdStr);
        //可以直接在mapper中用if判断是否用page的参数，此处为了校验两个代码的正确性就写了两个mapper方法
        if(pageRequest.getPageNum()!=0){
            // 计算偏移量
            int offset = (pageRequest.getPageNum() - 1) * pageRequest.getCount();
            // 执行分页查询
            list = vocMapper.getChapterVocsOfUserBook(
                    userId, pageRequest.getBookId(), offset, pageRequest.getCount());
        }else{
            list = vocMapper.getChapterVocsOfUserBookNoPage(
                    userId, pageRequest.getBookId());
        }
        // 获取总数
        int total = vocMapper.countChaptersInBook(pageRequest.getBookId());
        //converter转化为DisplayChapterDTO
        PageDTO<DisplayChapterDTO> displayChapterDTOPageDTO = vocConverter.displayChapterVocList2Page(list, (long) total);
        return displayChapterDTOPageDTO;
    }

    @Autowired
    UserFavoriteMapper userFavoriteMapper;

    @Override
    public VocDTO getVocDetail(Long vocId, Long userId) {
        VocDO vocDetail = vocMapper.getVocDetail(userId, vocId);
        List<UserVocExampleSentenceDO> userVocSentence = vocMapper.getUserVocExampleSentence(userId, vocId);
        if(vocDetail==null){
            throw new BusinessException(ResultCodeEnum.VOC_NOEXISTED);
        }
        vocDetail.setUserExamples(userVocSentence);

        LambdaQueryWrapper<UserFavoriteDO> favoriteWrapper = Wrappers.lambdaQuery(UserFavoriteDO.class)
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getVocId, vocId);
        // 获取用户是否收藏
        Long count = userFavoriteMapper.selectCount(favoriteWrapper);
        vocDetail.setFavorite(count > 0 ? 1 : 0);
        return vocConverter.vocDO2DTO(vocDetail);
    }

    @Override
    public UserBookStatisticsDTO getUserChooseCountInBook(Long userId, Long bookId) {
        return null;
    }

    @Override
    public void vocExcelValidate(MultipartFile file) throws IOException {
        // 1.创建用于读取数据的ReadListener对象, 泛型类型表示封装Excel每行数据的实体类
        AnalysisEventListener<VocExcelDTO> analysisEventListener = new MyHeaderReadListener(vocBookMapper, vocChapterMapper);

        // 2. 定义用来封装Excel每行数据的实体类的Class对象
        Class<VocExcelDTO> rowClass = VocExcelDTO.class;

        // 3. 调用EeasyExcel类的静态方法read，按行读取Excel文件中的数据
        EasyExcel.read(file.getInputStream(), rowClass, analysisEventListener)
                // 指定读取的sheet我们的一个excel只使用默认的一个sheet所以不用指定
                .sheet()
                // 开始读取,方法执行完毕，那么整个Excel文件也读取完了
                .doRead();
    }

    @Override
    @OperateLog(dateType = "词汇Excel", operateType = OperateLogConstant.OPERATE_EXCEL_ADD)
    public ExcelAddOperateDTO addVocExcel(MultipartFile file, Long userId) throws IOException {
        ExcelAddOperateDTO excelAddOperateDTO = new ExcelAddOperateDTO();
        excelAddOperateDTO.setFileName(file.getOriginalFilename());
        vocService.vocExcelValidate(file);
        MyReadListener myReadListener = new MyReadListener(vocService, vocBookMapper, vocChapterMapper);
        // 2. 定义用来封装Excel每行数据的实体类的Class对象
        Class rowClass = VocExcelDTO.class;

        // 3. 调用EeasyExcel类的静态方法read，按行读取Excel文件中的数据
        EasyExcel.read(file.getInputStream(), rowClass, myReadListener)
                // 指定读取的sheet我们的一个excel只使用默认的一个sheet所以不用指定
                .sheet()
                // 开始读取,方法执行完毕，那么整个Excel文件也读取完了
                .doRead();

        excelAddOperateDTO.setTotalCount(myReadListener.getTotalCount());
        return excelAddOperateDTO;

    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteVocFileOperateDTO deleteFile(Long id, String type, String name) {
        LambdaQueryWrapper<VocDO> vocDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
        vocDOLambdaQueryWrapper.eq(VocDO::getId, id);
        VocDO vocDO = vocMapper.selectOne(vocDOLambdaQueryWrapper);
        if ("uk".equals(type)) {
            vocDO.setUkPronounciation(null);
            vocMapper.update(vocDO, vocDOLambdaQueryWrapper);
        }
        if ("us".equals(type)) {
            vocDO.setUsPronounciation(null);
            vocMapper.update(vocDO, vocDOLambdaQueryWrapper);
        }
        fileUploadService.deleteFile(name);
        DeleteVocFileOperateDTO deleteVocFileOperateDTO = vocConverter.toDeleteVocFileOperateDTO(vocDO, type, name);
        return deleteVocFileOperateDTO;
    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteVocRelationOperateDTO deleteVocRelation(Long id) {
        VocChapBookDO vocChapBookDO = vocChapBookMapper.selectOne(
                new LambdaQueryWrapper<VocChapBookDO>()
                        .eq(VocChapBookDO::getId, id)
        );
        vocChapBookMapper.deleteById(id);
        return vocConverter.toDeleteVocRelationOperateDTO(vocChapBookDO);
    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteInterpretationOperateDTO deleteInterpretation(Long id) {
        VocMeaningDO vocMeaningDO = vocMeaningMapper.selectById(id);
        VocDO vocDO = vocMapper.selectOne(new LambdaQueryWrapper<VocDO>()
                .eq(VocDO::getId, vocMeaningDO.getVocId()));

        // 3. 删除记录
        int affectedRows = vocMeaningMapper.deleteById(id);

        return vocConverter.toDeleteInterpretationOperateDTO(vocMeaningDO, vocDO.getContent());
    }

    @Override
    @OperateLog(dateType = "词汇", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteVocExampleOperateDTO deleteExample(Long id) {
        ExampleSentenceDO exampleSentenceDO = exampleSentenceMapper.selectById(id);
        VocDO vocDO = vocMapper.selectOne(new LambdaQueryWrapper<VocDO>()
                .eq(VocDO::getId, exampleSentenceDO.getVocId()));

        // 3. 删除记录
        int affectedRows = exampleSentenceMapper.deleteById(id);

        return vocConverter.toDeleteExampleOperateDTO(exampleSentenceDO, vocDO.getContent());
    }
}
